package com.android.whereismy.mail;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.search.StringTerm;
import javax.mail.search.SubjectTerm;

import android.content.res.Resources;
import android.util.Log;

import com.android.whereismy.R;
import com.android.whereismy.util.CmnConsts;
import com.sun.mail.imap.IMAPFolder;

/**
 * MailControler
 * 
 * @author akarae
 */
public class MailControler extends Authenticator  {
    /** Unit Id. */
    private String unitID;
    /** Unit Password. */
    private String unitPWD;

    /** ControlCenter Id. */
    private String ccID;
    /** ControlCenter Password. */
    private String ccPWD;

    /** Unit MailAddress. */
    private String rptMailFrom;
    /** Control-Center MailAddress. */
    private String rptMailTo;
    
    // MailControler contructor
    public MailControler(Resources resources) {
        unitID = resources.getString(R.string.unit_id);
        unitPWD = resources.getString(R.string.unit_pwd);
        
        ccID = resources.getString(R.string.cc_id);
        ccPWD = resources.getString(R.string.cc_pwd);
        
        rptMailFrom = resources.getString(R.string.unit_mail);
        rptMailTo = resources.getString(R.string.cc_mail);
    }
    
    /**
     * receiveMail.
     * @param searchKey unit ID that will be searched
     * @param authKey authentic key that identify the unit
     * @throws Exception throws all of Exception
     */
    public final Map <String, Object> receiveMail(final String searchKey, final String authKey) throws Exception {
        // incoming port 993
        Map <String, Object> resultMap = new HashMap <String, Object> ();

        // setup properties
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", "imaps");

        // get session
        Session session = Session.getDefaultInstance(props);
        Store store = session.getStore("imaps");
        store.connect("imap.gmail.com", ccID, ccPWD);

        // get IMAP folder
        IMAPFolder imapBox = (IMAPFolder) store.getFolder("Inbox");
        imapBox.open(Folder.READ_ONLY);
        
        // search folder
        StringTerm st = new SubjectTerm(searchKey);
        Message [] messagesImap = imapBox.search(st);
        // when no message
        if (messagesImap == null) {
            Log.d(CmnConsts.DEBUG_TAG, "there is no Message(NULL)");
            throw new Exception("there is no report");
        }
        String temp = messagesImap[messagesImap.length - 1].getSubject();
        String [] infoArr = temp.split(CmnConsts.SEPARATOR);
        // when parameter has a trouble
        if (infoArr.length != CmnConsts.PARAM_COUNT) {
            Log.d(CmnConsts.DEBUG_TAG, "parameter counter has an Exception");
            throw new Exception("mail title check failure");
        }
        imapBox.close(false);
        store.close();
        
        // setup result map
        resultMap.put(CmnConsts.LAT, Integer.valueOf(infoArr[3]));
        resultMap.put(CmnConsts.LONG, Integer.valueOf(infoArr[4]));
        resultMap.put(CmnConsts.RPT_TIME, messagesImap[messagesImap.length-1].getSentDate());
        resultMap.put(CmnConsts.PROVIDER, String.valueOf(infoArr[5]));
        
        return resultMap;
    }

    /**
     * sendMail.
     * @param unitId unit ID
     * @param unitLat unit Latitude
     * @param unitLong unit Longitude
     * @param unitAuthKey unit Authentication Key
     * @throws Exception throws all of Exception
     */
    public final void sendMail(
            final String unitId,
            final String unitAuthKey,
            final String unitLat,
            final String unitLong,
            final String provider) throws Exception {
        // setup Properties
        Properties prop = new Properties();
        // port 25, 467 was failed
        prop.put("mail.smtp.port", "587");
        prop.put("mail.smtp.socketFactory.fallback", "false");
        prop.put("mail.smtp.quitwait", "false");
        prop.put("mail.smtp.host", "smtp.gmail.com");
        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.starttls.enable", "true");

        // get Session
        Session session = Session.getDefaultInstance(prop);

        // create Message
        Message msg = new MimeMessage(session);
        msg.setSubject(CmnConsts.HEADER + CmnConsts.SEPARATOR
                + unitId + CmnConsts.SEPARATOR
                + unitAuthKey + CmnConsts.SEPARATOR
                + unitLat + CmnConsts.SEPARATOR
                + unitLong + CmnConsts.SEPARATOR
                + provider);

        InternetAddress from = new InternetAddress(rptMailFrom);
        InternetAddress to = new InternetAddress(rptMailTo);
        msg.addRecipient(Message.RecipientType.TO, to);
        msg.setFrom(from);

        Multipart multipart = new MimeMultipart("related");
        BodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent("", "text/plain");
        multipart.addBodyPart(htmlPart);
        msg.setContent(multipart);

        // send a message
        Transport transport = session.getTransport("smtp");
        transport.connect(unitID, unitPWD);
        transport.sendMessage(msg, msg.getAllRecipients());
        transport.close();
        
    }
}
